package cn.edu.tju.ldj.analytics.utils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Vector;



/**
 * 其他人无需了解，反射调用工具
 * @author cjy
 *	
 */

public class IReflectUtil {
	
	/**
	 * 载入一个类的实例
	 * @param className
	 * @return
	 * @throws ClassNotFoundException
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
	@SuppressWarnings("rawtypes")
	public Object loadInstance(String className) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
		Class clazz = Class.forName(className);		
		Object object = clazz.newInstance();
		return object;
	}
	
	/**
	 * 
	 * 列出一个对象所有的属性
	 * @author cjy
	 * @param obj
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 */
	public void listAllfields(Object obj) throws IllegalArgumentException, IllegalAccessException{
		Field[] fields=obj.getClass().getFields();
		for(int i=0;i<fields.length;i++){
			System.out.println(fields[i].getName());
			fields[i].set(obj, String.valueOf(i));
		}
		
	}
	
	@SuppressWarnings("rawtypes")
	public void cloneObj(Object src,Object target) throws IllegalArgumentException, IllegalAccessException, CloneNotSupportedException{
		Field[] fields=src.getClass().getFields();
		for(int i=0;i<fields.length;i++){
			System.out.println(fields[i].getName());
			Object orgField =fields[i].get(src);
			if(null==orgField){
			fields[i].set(target, null);
			}else if(orgField instanceof java.lang.String){
				fields[i].set(target, new String((String)orgField));
			}else if(orgField instanceof java.lang.Integer){
				fields[i].set(target, new Integer((Integer)orgField));
			}else if(orgField instanceof java.lang.Long){
				fields[i].set(target, new Long((Long)orgField));
			}else if(orgField instanceof java.lang.Double){
				fields[i].set(target, new Double((Double)orgField));
			}else if(orgField instanceof java.lang.Float){
				fields[i].set(target, new Float((Float)orgField));
			}else if(orgField instanceof java.lang.Boolean){
				fields[i].set(target, new Boolean((Boolean)orgField));
			}else if(orgField instanceof java.util.Vector){
				fields[i].set(target, ((Vector)orgField).clone());
			}else if(orgField instanceof java.util.HashSet){
				fields[i].set(target, ((HashSet)orgField).clone());
			}else{
				throw new java.lang.CloneNotSupportedException(orgField.getClass().toString());
			}
			 
		}
	}
	
	/**
	 * 设置一个对象的属性值，如果fieldName=abc，则会激发obj.setAbs(value)方法
	 * @author cjy
	 * @param obj
	 * @param fieldName
	 * @param value
	 * @throws SecurityException
	 * @throws NoSuchMethodException
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 */
	@SuppressWarnings("rawtypes")
	public void setField(Object obj,String fieldName,Object value) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException{
		Class[] args=new Class[1];
		args[0]=value.getClass(); 		
		String methodName="set"+fieldName.substring(0,1).toUpperCase()+ fieldName.substring(1,fieldName.length());
		Method method = obj.getClass().getMethod(methodName, args);
		method.invoke(obj,value);
	}
	
	/**
	 * 
	 * 激发 obj的methodName方法，参数为 args
	 * @author cjy
	 * @param obj
	 * @param methodName
	 * @param args
	 * @return
	 * @throws SecurityException
	 * @throws NoSuchMethodException
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 */
	@SuppressWarnings("rawtypes")
	public Object invoke(Object obj,String methodName,Object...args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException{
		
		Class[] argClass=new Class[args.length];
		for(int i=0;i<args.length;i++){
			argClass[i]=args[i].getClass();
		}
		Method method = obj.getClass().getMethod(methodName, argClass);
		// 调用得到的方法，并给方法传递参数（如果有参）。
		return method.invoke(obj,new Object[] {});
	}

}
